package com.management.department.teacherinfosystem.Service;

import com.management.department.teacherinfosystem.DTO.ResearchFinishDTO;
import com.management.department.teacherinfosystem.DTO.ResearchFundingDTO;
import com.management.department.teacherinfosystem.DTO.ResearchMemberDTO;
import com.management.department.teacherinfosystem.DTO.ResearchProjectSubmitDTO;
import com.management.department.teacherinfosystem.Entity.*;
import com.management.department.teacherinfosystem.Repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Service
public class ResearchProjectServiceImpl implements ResearchProjectService {

    @Autowired
    private ResearchProjectRepository projectRepository;
    @Autowired
    private ResearchProjectMemberRepository memberRepository;
    @Autowired
    private ResearchProjectFundingRepository fundingRepository;
    @Autowired
    private AttachmentRepository attachmentRepository;
    @Autowired
    private UserRepository userRepository;

    @Value("${file.upload.research-dir:D:/research_attachments/}")
    private String researchUploadDir;

    @Value("${file.upload.research-finish-dir:D:/research_finish_attachments/}")
    private String researchFinishUploadDir;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveProjectWithMembersAndFile(ResearchProjectSubmitDTO dto, MultipartFile[] files) throws Exception {
        // 1. 保存项目主表
        ResearchProject project = new ResearchProject();
        project.setName(dto.getName());
        project.setProjectNumber(dto.getProjectNumber());
        project.setProjectType(dto.getProjectType());
        project.setSubjectCategory(dto.getSubjectCategory());
        project.setLevel(dto.getLevel());
        project.setSourceUnit(dto.getSourceUnit());
        
        // 设置负责人ID（使用当前登录用户）
        org.springframework.security.core.Authentication auth = 
            org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            String currentUsername = auth.getName();
            User currentUser = userRepository.findByUsername(currentUsername).orElse(null);
            if (currentUser != null) {
                project.setLeaderId(currentUser.getId());
            } else {
                throw new RuntimeException("当前用户不存在: " + currentUsername);
            }
        } else {
            throw new RuntimeException("未登录或认证信息丢失");
        }
        
        // 自动生成项目编号：RSP + 年份 + 月份 + 6位递增序号
        if (dto.getProjectNumber() == null || dto.getProjectNumber().trim().isEmpty()) {
            String autoProjectNumber = generateProjectNumber();
            project.setProjectNumber(autoProjectNumber);
        }
        
        project.setStatus("申报中");  // 初始状态为申报中

        // 日期转换
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        project.setApplicationDate(isValidDateString(dto.getApplicationDate()) ? sdf.parse(dto.getApplicationDate()) : null);
        project.setStartDate(isValidDateString(dto.getStartDate()) ? sdf.parse(dto.getStartDate()) : null);
        project.setEndDate(isValidDateString(dto.getEndDate()) ? sdf.parse(dto.getEndDate()) : null);

        // 经费信息
        project.setTotalFunding(dto.getTotalFunding());
        project.setFundingSource(dto.getFundingSource());
        project.setFundingStatus(dto.getFundingStatus());
        
        // 项目描述
        project.setDescription(dto.getDescription());

        project.setCreatedAt(new Date());
        project.setUpdatedAt(new Date());

        // 保存项目
        ResearchProject savedProject = projectRepository.save(project);

        // 2. 保存项目成员
        if (dto.getMembers() != null) {
            for (ResearchMemberDTO m : dto.getMembers()) {
                ResearchProjectMember member = new ResearchProjectMember();
                member.setProjectId(savedProject.getId());
                
                // 优先使用前端提供的userId，否则根据工号查找用户
                if (m.getUserId() != null) {
                    // 前端已经提供了userId，直接使用
                    member.setUserId(m.getUserId());
                    member.setName(m.getName());
                    member.setDepartment(m.getDepartment());
                } else if (m.getStaffNo() != null && !m.getStaffNo().trim().isEmpty()) {
                    // 根据工号查找对应用户
                    User u = userRepository.findByStaffNo(m.getStaffNo()).orElse(null);
                    if (u != null) {
                        member.setUserId(u.getId());
                        member.setName(u.getName());
                        member.setDepartment(u.getDepartment());
                    } else {
                        member.setName(m.getName());
                        member.setDepartment(m.getDepartment());
                    }
                } else {
                    member.setName(m.getName());
                    member.setDepartment(m.getDepartment());
                }
                
                member.setStaffNo(m.getStaffNo());
                member.setRole(m.getRole());
                member.setResponsibility(""); // 暂时不使用职责描述
                member.setCreatedAt(new Date());
                memberRepository.save(member);
            }
        }

        // 3. 保存项目经费详情
        if (dto.getFundings() != null) {
            for (ResearchFundingDTO fundingDto : dto.getFundings()) {
                if (fundingDto.getAmount() != null && fundingDto.getSource() != null && !fundingDto.getSource().trim().isEmpty()) {
                    ResearchProjectFunding funding = new ResearchProjectFunding();
                    funding.setProjectId(savedProject.getId());
                    funding.setAmount(fundingDto.getAmount());
                    funding.setSource(fundingDto.getSource());
                    funding.setPurpose(fundingDto.getPurpose());
                    funding.setStatus(fundingDto.getStatus() != null ? fundingDto.getStatus() : "未到账");
                    
                    if (isValidDateString(fundingDto.getExpectedDate())) {
                        funding.setExpectedDate(sdf.parse(fundingDto.getExpectedDate()));
                    }
                    if (isValidDateString(fundingDto.getActualDate())) {
                        funding.setActualDate(sdf.parse(fundingDto.getActualDate()));
                    }
                    
                    funding.setCreatedAt(new Date());
                    fundingRepository.save(funding);
                }
            }
        }

        // 4. 保存附件
        if (files != null && files.length > 0) {
            File dir = new File(researchUploadDir);
            if (!dir.exists()) dir.mkdirs();
            
            for (MultipartFile file : files) {
                if (file == null || file.isEmpty()) continue;
                String saveName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
                File dest = new File(researchUploadDir + saveName);
                file.transferTo(dest);

                Attachment attachment = new Attachment();
                attachment.setFileName(file.getOriginalFilename());
                attachment.setFileUrl(researchUploadDir + saveName);
                attachment.setRelatedType("research_project");
                attachment.setRelatedId(savedProject.getId());
                attachment.setUploadedBy(savedProject.getLeaderId());
                attachment.setUploadedAt(new Date());
                attachmentRepository.save(attachment);
            }
        }

        return savedProject.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteProject(Long id) throws Exception {
        ResearchProject project = projectRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("项目不存在"));

        // 1. 删除项目成员
        memberRepository.deleteByProjectId(id);
        
        // 2. 删除项目经费
        fundingRepository.deleteByProjectId(id);
        
        // 3. 删除附件记录（实际文件保留）
        attachmentRepository.deleteByRelatedIdAndRelatedType(id, "research_project");
        
        // 4. 删除项目本身
        projectRepository.delete(project);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resubmitProject(Long id, ResearchProjectSubmitDTO dto, MultipartFile[] files) throws Exception {
        ResearchProject project = projectRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("项目不存在"));

        if (!"已驳回".equals(project.getStatus())) {
            throw new RuntimeException("只有已驳回的项目可以重新提交！");
        }

        // 1. 更新主表字段
        project.setName(dto.getName());
        project.setProjectType(dto.getProjectType());
        project.setSubjectCategory(dto.getSubjectCategory());
        project.setLevel(dto.getLevel());
        project.setSourceUnit(dto.getSourceUnit());

        // 负责人处理（保持原负责人不变）
        // 注意：重新提交时不应该更改负责人，所以这里不设置leaderId
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        project.setApplicationDate(isValidDateString(dto.getApplicationDate()) ? sdf.parse(dto.getApplicationDate()) : null);
        project.setStartDate(isValidDateString(dto.getStartDate()) ? sdf.parse(dto.getStartDate()) : null);
        project.setEndDate(isValidDateString(dto.getEndDate()) ? sdf.parse(dto.getEndDate()) : null);
        
        // 经费信息
        project.setTotalFunding(dto.getTotalFunding());
        project.setFundingSource(dto.getFundingSource());
        project.setFundingStatus(dto.getFundingStatus());
        
        // 项目描述
        project.setDescription(dto.getDescription());
        
        project.setUpdatedAt(new Date());
        
        // 根据项目类型决定重新提交后的状态
        // 如果是结题审核被驳回的项目，重新提交后应该回到"结题审核中"状态
        // 如果是申报被驳回的项目，重新提交后回到"申报中"状态
        // 主要检查项目是否有结题信息
        boolean hasFinishInfo = (project.getFinishDate() != null) 
                               || (project.getFinishType() != null && !project.getFinishType().trim().isEmpty())
                               || (project.getFinishReviewOpinion() != null && !project.getFinishReviewOpinion().trim().isEmpty())
                               || (project.getFinishReviewerId() != null);
        
        System.out.println("DEBUG: 重新提交科研项目ID=" + id);
        System.out.println("DEBUG: finishDate=" + project.getFinishDate());
        System.out.println("DEBUG: finishType=" + project.getFinishType());
        System.out.println("DEBUG: finishReviewOpinion=" + project.getFinishReviewOpinion());
        System.out.println("DEBUG: finishReviewerId=" + project.getFinishReviewerId());
        System.out.println("DEBUG: hasFinishInfo=" + hasFinishInfo);
        
        if (hasFinishInfo) {
            // 有结题信息，说明是结题审核被驳回，重新提交后回到"结题审核中"
            System.out.println("DEBUG: 设置状态为结题审核中");
            project.setStatus("结题审核中");
        } else {
            // 没有结题信息，说明是申报被驳回，重新提交后回到"申报中"
            System.out.println("DEBUG: 设置状态为申报中");
            project.setStatus("申报中");
        }

        // 2. 处理经费（删除旧，新增新）
        fundingRepository.deleteByProjectId(id);
        if (dto.getFundings() != null && !dto.getFundings().isEmpty()) {
            for (ResearchFundingDTO fundingDto : dto.getFundings()) {
                if (fundingDto.getAmount() != null && fundingDto.getSource() != null && !fundingDto.getSource().trim().isEmpty()) {
                    ResearchProjectFunding funding = new ResearchProjectFunding();
                    funding.setProjectId(id);
                    funding.setAmount(fundingDto.getAmount());
                    funding.setSource(fundingDto.getSource());
                    funding.setPurpose(fundingDto.getPurpose());
                    funding.setStatus(fundingDto.getStatus() != null ? fundingDto.getStatus() : "未到账");
                    
                    if (isValidDateString(fundingDto.getExpectedDate())) {
                        funding.setExpectedDate(sdf.parse(fundingDto.getExpectedDate()));
                    }
                    if (isValidDateString(fundingDto.getActualDate())) {
                        funding.setActualDate(sdf.parse(fundingDto.getActualDate()));
                    }
                    
                    funding.setCreatedAt(new Date());
                    fundingRepository.save(funding);
                }
            }
        }

        // 3. 处理成员（删除旧，新增新）
        memberRepository.deleteByProjectId(id);
        if (dto.getMembers() != null) {
            for (ResearchMemberDTO m : dto.getMembers()) {
                ResearchProjectMember member = new ResearchProjectMember();
                member.setProjectId(id);
                
                // 如果有工号，查找对应用户
                if (m.getStaffNo() != null && !m.getStaffNo().trim().isEmpty()) {
                    User u = userRepository.findByStaffNo(m.getStaffNo()).orElse(null);
                    if (u != null) {
                        member.setUserId(u.getId());
                        member.setName(u.getName());
                        member.setDepartment(u.getDepartment());
                    } else {
                        member.setName(m.getName());
                        member.setDepartment(m.getDepartment());
                    }
                } else {
                    member.setName(m.getName());
                    member.setDepartment(m.getDepartment());
                }
                
                member.setStaffNo(m.getStaffNo());
                member.setRole(m.getRole());
                member.setResponsibility(""); // 暂时不使用职责描述
                member.setCreatedAt(new Date());
                memberRepository.save(member);
            }
        }

        // 4. 处理附件（删除旧，新增新）
        attachmentRepository.deleteByRelatedIdAndRelatedType(id, "research_project");
        if (files != null && files.length > 0) {
            File dir = new File(researchUploadDir);
            if (!dir.exists()) dir.mkdirs();
            
            for (MultipartFile file : files) {
                if (file == null || file.isEmpty()) continue;
                String saveName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
                File dest = new File(researchUploadDir + saveName);
                file.transferTo(dest);

                Attachment attachment = new Attachment();
                attachment.setFileName(file.getOriginalFilename());
                attachment.setFileUrl(researchUploadDir + saveName);
                attachment.setRelatedType("research_project");
                attachment.setRelatedId(id);
                attachment.setUploadedBy(project.getLeaderId());
                attachment.setUploadedAt(new Date());
                attachmentRepository.save(attachment);
            }
        }

        projectRepository.save(project);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitFinishMaterials(Long id, ResearchFinishDTO dto, MultipartFile[] files) throws Exception {
        ResearchProject project = projectRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("项目不存在"));

        if (!"执行中".equals(project.getStatus())) {
            throw new RuntimeException("只有执行中的项目才能提交结题材料");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        project.setFinishDate(dto.getFinishDate() != null ? sdf.parse(dto.getFinishDate()) : null);
        project.setFinishType(dto.getFinishType());
        project.setFinishLevel(dto.getFinishLevel());
        project.setFinishResults(dto.getFinishResults());
        project.setResultsList(dto.getResultsList());
        project.setStatus("结题审核中");
        project.setUpdatedAt(new Date());
        projectRepository.save(project);

        // 保存结题材料附件
        if (files != null && files.length > 0) {
            File dir = new File(researchFinishUploadDir);
            if (!dir.exists()) dir.mkdirs();
            
            for (MultipartFile file : files) {
                if (file.isEmpty()) continue;
                String saveName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
                File dest = new File(researchFinishUploadDir + saveName);
                file.transferTo(dest);

                Attachment attachment = new Attachment();
                attachment.setFileName(file.getOriginalFilename());
                attachment.setFileUrl(researchFinishUploadDir + saveName);
                attachment.setRelatedType("research_project_finish");
                attachment.setRelatedId(id);
                attachment.setUploadedAt(new Date());
                attachmentRepository.save(attachment);
            }
        }
    }

    /**
     * 检查日期字符串是否有效
     */
    private boolean isValidDateString(String dateStr) {
        return dateStr != null && !dateStr.trim().isEmpty();
    }

    /**
     * 自动生成项目编号：RSP + 年份 + 月份 + 6位递增序号
     */
    private String generateProjectNumber() {
        Date now = new Date();
        SimpleDateFormat yearMonthFormat = new SimpleDateFormat("yyyyMM");
        String yearMonth = yearMonthFormat.format(now);
        
        String prefix = "RSP" + yearMonth;
        long randomSequence = System.currentTimeMillis() % 1000000;
        
        return String.format("%s%06d", prefix, randomSequence);
    }
}
